﻿using System;
using System.Linq;
using System.Web;
using Eneta.Portal.Common.Repository;
using Microsoft.SharePoint;
using Microsoft.SharePoint.ApplicationRuntime;

namespace Eneta.Portal.Common
{
    public class EnetaApplication : SPHttpApplication, IVaryByCustomHandler 
    {
        public override void Init()
        {
            base.Init();

            RegisterGetVaryByCustomStringHandler(this); 

            Error += EnetaApplicationError;
        }

        void EnetaApplicationError(object sender, EventArgs e)
        {
            
        }
        
        public string GetVaryByCustomString(HttpApplication app, HttpContext context, string custom)
        {
            if (string.IsNullOrEmpty(custom))
                return null;

            var cacheString = string.Empty;
            var keys = custom.Split(";".ToCharArray());
            var item = SPContext.Current.Item;

            foreach (string key in keys)
            {
                if (key == "AnnouncementModified")
                {
                    if(item != null)
                        cacheString += ":AnnouncementModified=" + GetAnnouncementModified(item.ID);
                }
                else if(key == "LastAnnouncementModified")
                {
                    cacheString += ":LastAnnouncementModified=" + GetAnnouncementLastModified();
                }
                else if (key == "Role")
                {
                    cacheString += ":Role=" + GetRoleString();
                }
                else if (key == "UserName")
                {
                    cacheString += ":UserName=" + GetUserNameString();
                }
                else if (key == "BlogEntryModified")
                {
                    if(item != null)
                        cacheString += ":BlogEntryModifed=" + GetBlogEntryModified(item.ID);
                }
                else if(key=="LastBlogEntryModified")
                {
                    cacheString += ":LastBlogEntryModified=" + GetBlogEntryLastModified();
                }
                else if(key=="EventModified")
                {
                    if(item != null)
                        cacheString += ":EventModified=" + GetEventModified(item.ID);
                }
                else if(key=="LastEventModified")
                {
                    cacheString += ":LastEventModified=" + GetEventLastModified();
                }
                else if(key == "HtmlModified")
                {
                    var rep = new HtmlRepository(SPContext.Current.Web);
                    cacheString += ":HtmlModified" + rep.GetLastChangeDate();
                }
                else if(key == "ProfilesModified")
                {
                    var rep = new UserProfileRepository(SPContext.Current.Web);
                    cacheString += ":ProfilesModified" + rep.GetLastChangeDate();
                }
                else if(key == "LastNewsModified")
                {
                    if(item != null)
                    {
                        var annModified = GetAnnouncementLastModified();
                        var entryModified = GetBlogEntryLastModified();
                        DateTime modifiedDate;

                        if(annModified > entryModified)
                            modifiedDate = annModified;
                        else 
                            modifiedDate = entryModified;

                        cacheString += ":LastNewsModified=" + modifiedDate;
                    }
                }
            }
            if (!string.IsNullOrEmpty(cacheString))
                if (cacheString[0] == ':')
                    cacheString = cacheString.Substring(1);

            Logger.LogInfo("EnetaCacheKey(" + custom + "): " + cacheString, "EnetaApplication");

            return cacheString;
        }

        private string GetUserNameString()
        {
            if (SPContext.Current == null)
                return string.Empty;

            var user = SPContext.Current.Web.CurrentUser;
            if (user == null)
                return string.Empty;

            return user.LoginName;
        }


        private DateTime GetBlogEntryModified(int id)
        {
            var rep = new BlogRepository(SPContext.Current.Web);
            var entry = rep.GetBlogEntryById(id);
            if (entry == null)
                return DateTime.MinValue;

            var modified = entry.Modified;
            var lastComment = from c in entry.Comments
                              orderby c.Created descending
                              select c;

            if (lastComment.Count() > 0)
            {
                var commModified = lastComment.First().Modified;
                if (commModified > modified)
                    modified = commModified;
            }

            return modified;
        }

        private DateTime GetBlogEntryLastModified()
        {
            var rep = new BlogRepository(SPContext.Current.Web);
            var lastModifiedDate = rep.GetLastModifiedDate();
            return lastModifiedDate;
        }

        private DateTime GetAnnouncementModified(int id)
        {
            var rep = new AnnouncementRepository(SPContext.Current.Web);
            var ann = rep.GetAnnouncementById(id);
            if (ann == null)
                return DateTime.MinValue;

            var modified = ann.Modified;
            var lastComment = from c in ann.Comments
                              orderby c.Created descending
                              select c;

            if(lastComment.Count() > 0)
            {
                var commModified = lastComment.First().Modified;
                if (commModified > modified)
                    modified = commModified;
            }

            return modified;
        }

        private DateTime GetAnnouncementLastModified()
        {
            var rep = new AnnouncementRepository(SPContext.Current.Web);
            var lastModifiedDate = rep.GetLastModifiedDate();
            return lastModifiedDate;
        }

        private string GetRoleString()
        {
            var spContext = SPContext.Current;
            if (spContext == null)
                return "Anon";

            var user = spContext.Web.CurrentUser;
            if (user == null)
                return "Anon";
            return user.IsSiteAdmin ? "Admin" : "Dumb";
        }

        private DateTime GetEventModified(int id)
        {
            var rep = new EventRepository(SPContext.Current.Web);
            var entry = rep.GetEventById(id);
            if (entry == null)
                return DateTime.MinValue;

            var modified = entry.Modified;

            var users = rep.GetEventAttendees(id);

            var lastReg = from c in users
                              orderby c.Modified descending
                              select c;

            if (lastReg.Count() > 0)
            {
                var regModified = lastReg.First().Modified;
                if (regModified > modified)
                    modified = regModified;
            }

            return modified;
        }



        private DateTime GetEventLastModified()
        {
            var rep = new EventRepository(SPContext.Current.Web);
            var lastModifiedDate = rep.GetLastModifiedDate();
            return lastModifiedDate;
        }
    }
}
